#ifndef __UP_TREATY_H__
#define __UP_TREATY_H__

#include <iostream>
#include <vector>
#include "treaty_base.h"
#include "dev_data.h"
#include "config.h"
using namespace std;

#define TREATY_HEADE_LEN 6
typedef union __u8_u16_u32_float_str
{
    uint8_t u8;
    uint16_t u16;
    uint32_t u32;
    float float_val;
    char str[32];
} u8_u16_u32_float_str_t;

class up_treaty : public treaty_base
{
private:
    u8_u16_u32_float_str_t reg_heart;

    shared_ptr<dev_data> mp_dev_data;

private:
    uint16_t event_id;             // 事务处理标识符
    OPS ops;                       // 当前帧的功能码
    DEV dev_type;                  // dq检测设备类型
    vector<uint8_t> vec_temp;      // 数据域
    vector<uint8_t> vec_recv_data; // 数据域
    vector<uint8_t> vec_send_data; // 数据域
private:
    zlog_category_t *log_up_treaty;

private:
    /**
     * @brief 获取当前系统时间并保存到输入参数数组中
     *
     * 时间格式：time[0] = 年, time[1] = 月, time[2] = 日,
     *          time[3] = 时, time[4] = 分, time[5] = 秒
     *
     * @param time 指向长度为6的uint16_t数组，用于存储时间
     * @return int 成功返回1，失败返回0
     */
    int get_system_time(uint16_t time[6]);

public:
    // 使用 = delete 明确删除复制操作
    up_treaty();

    /**
     * @brief 创建错误帧
     * @param vec_data 错误帧数据
     * @param Exception_Code 异常码
     * @param Function_Code 功能码
     * @return uint32_t 错误帧数据长度
     *
     * | 异常码（十六进制） | 名称                                        | 含义               | 可能原因                                        |
    | ------------------ | ------------------------------------------- | ------------------ | ----------------------------------------------- |
    | `0x01`             | **Illegal Function**                        | 非法功能                             | 请求的功能码不支持（如从站不支持 FC=0x10）      |
    | `0x02`             | **Illegal Data Address**                    | 非法数据地址                | 寄存器地址超出范围（如访问 400001~499999 之外） |
    | `0x03`             | **Illegal Data Value**                      | 非法数据值                           | 写入的值无效（如长度不对、值越界）              |
    | `0x04`             | **Slave Device Failure**                    | 从站设备故障                    | 设备内部错误（如硬件故障、程序崩溃）            |
    | `0x05`             | **Acknowledge**                             | 确认                                    | 命令已接收，但需长时间处理（少见）              |
    | `0x06`             | **Slave Device Busy**                       | 从站设备忙                       | 设备正忙，无法处理请求（可稍后重试）            |
    | `0x08`             | **Memory Parity Error**                     | 存储奇偶校验错误               | 存储器读写出错（较老设备）                      |
    | `0x0A`             | **Gateway Path Unavailable**                | 网关路径不可用               | Modbus 网关问题（跨网络通信失败）               |
    | `0x0B`             | **Gateway Target Device Failed to Respond** | 网关目标设备无响应 | 目标设备未响应网关请求                          |

     */
    uint32_t create_error_frame(vector<uint8_t> &frame, uint8_t Exception_Code = 02, uint8_t Function_Code = 02);

    /**
     * @brief 创建Treaty头
     *
     * @param vec
     * @param ev_id
     * @param data
     * @return uint32_t
     */
    uint32_t create_write_reg_frame(vector<uint8_t> &frame, uint16_t reg_addr_start, uint16_t reg_num);

    uint32_t read_reg_value(vector<uint8_t> &frame, const uint16_t reg_addr_start, const uint16_t reg_num);

    uint32_t classfy_parse_frame(vector<uint8_t> &frame, vector<uint8_t> &return_data);

    // 获取寄存器数据
    uint16_t get_reg_value(vector<uint8_t> &vec_data, DEV_REG reg_addr, const uint16_t reg_num);
    // 设置寄存器数据
    uint16_t set_reg_value(vector<uint8_t> &vec_data, vector<uint8_t> &return_data, const uint16_t reg_addr, const uint16_t reg_num);
    /**
     * @brief 构建响应状态数据自动推送包
     *
     * @param frame 输出的数据包
     * @param rsp_num 响应状态数量
     * @param dev_type 设备类型 0:本地数据；1：阿尔法；2：贝塔；3：伽马
     * @return uint16_t 数据域长度
     */
    uint16_t build_rsp_status_data_packet(vector<uint8_t> &frame, const uint16_t rsp_num, const PUSH_DATA_TYPE dev_type);
    // 构建测量结果自动推送数据包
    uint16_t build_rsp_result_data_packet(vector<uint8_t> &vec_data, const uint16_t rsp_num, const PUSH_DATA_TYPE measure_dir);

    /**
     * @brief 构建响应其他附加数据自动推送包
     *
     * @param frame 输出的数据包
     * @param dev_type 设备类型
     * @return uint16_t 数据域长度
     */
    uint16_t build_rsp_others_data_packet(vector<uint8_t> &frame, const PUSH_DATA_TYPE data_type);
};

#endif
